package com.zx.framework.core.util;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import com.zx.framework.core.exception.FrameworkException;

// TODO: Auto-generated Javadoc
/**
 * The Class SecurityUtil.
 *
 * @日期: 2013-03-08
 * @描述: 加密解密工具类。<br/>
 */
public class SecurityUtil {
	
	//16位长的默认密钥
	/** The Constant KEY_16. */
	private static final String KEY_16 = "DC25D384ACB34ECA";

	/**
	 * 将字符串进行md5加密.
	 * 
	 * @param input
	 *            输入值
	 * @return the string
	 */
	public static String md5(String input) {
		if (StringUtil.isEmpty(input)) {
			throw new FrameworkException("MD5加密字符串不能为空！");
		}
		return DigestUtils.md5Hex(input);
	}

	/**
	 * base64编码.
	 * 
	 * @param input
	 *            输入值
	 * @return the string
	 */
	public static String encodeBase64(String input) {
		if (StringUtil.isEmpty(input)) {
			throw new FrameworkException("Base64加密字符串不能为空！");
		}
		return new String(Base64.encodeBase64(input.getBytes(), true));
	}

	/**
	 * base64解码.
	 * 
	 * @param input
	 *            输入值
	 * @return the string
	 */
	public static String decodeBase64(String input) {
		if (StringUtil.isEmpty(input)) {
			throw new FrameworkException("Base64解密字符串不能为空！");
		}
		return new String(Base64.decodeBase64(input));
	}

	/**
	 * AES加密.
	 *
	 * @param sSrc 输入值
	 * @param sKey 16位密钥
	 * @return the string
	 * @author wangguowei
	 */
	public static String encryptAES(String sSrc, String sKey)   {
		//验证密钥规则
		if (sKey == null || sKey.length() != 16){
			throw new FrameworkException("AES,密钥格式不正确");
		}
		
		//加密结果
		byte[] encrypted;
		try{
			byte[] raw = sKey.getBytes("utf-8");
			SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
			encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
		}catch(Exception e){
			throw new FrameworkException(e);
		}
		return Base64.encodeBase64URLSafeString(encrypted);
	}
	
	/**
	 * AES加密.
	 *
	 * @param sSrc 输入值
	 * @param sKey 16位密钥
	 * @return the string
	 * @author wangguowei
	 */
	public static byte[] encryptByteAES(byte[] sSrc, String sKey)   {
		//验证密钥规则
		if (sKey == null || sKey.length() != 16){
			throw new FrameworkException("AES,密钥格式不正确");
		}
		
		//加密结果
		byte[] encrypted;
		try{
			byte[] raw = sKey.getBytes("utf-8");
			SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
			encrypted = cipher.doFinal(sSrc);
		}catch(Exception e){
			throw new FrameworkException(e);
		}
		return encrypted;
	}
	/**
	 * AES加密.
	 *
	 * @param sSrc 输入值
	 * @param sKey 16位密钥
	 * @return the string
	 * @author wangguowei
	 */
	public static byte[] encryptByteAES(byte[] sSrc)   {
		return encryptByteAES(sSrc, KEY_16);
	}
	/**
	 * Encrypt AES. 使用固定的默认密钥进行加密
	 *
	 * @param sSrc 加密源数据
	 * @return the string
	 */
	public static String encryptAES(String sSrc){
		return encryptAES(sSrc,KEY_16);
	}
	
	/**
	 * Encryt zxcb. 使用 默认密钥 将地址加密成 中讯链接
	 *
	 * @param sSrc the s src
	 * @return the string
	 */
	public static String encryptZXCB(String sSrc){
		return "zxcb://"+encryptAES(sSrc,KEY_16)+"!";
	}

	/**
	 * AES解密.
	 *
	 * @param sSrc 输入值
	 * @param sKey 16位密钥
	 * @return the string
	 */
	public static String decryptAES(String sSrc, String sKey){
		
		//验证密钥规则
		if (sKey == null || sKey.length() != 16){
			throw new FrameworkException("AES,密钥格式不正确");
		}
		
		byte[] encrypted = new Base64().decode(sSrc);
		
		try {
			byte[] original = decryptByteAES(encrypted, sKey);
			String originalString = new String(original, "utf-8");
			return originalString;
		} catch (Exception e) {
			throw new FrameworkException(e);
		}
	}
	
	/**
	 * AES解密.
	 *
	 * @param sSrc 输入值
	 * @param sKey 16位密钥
	 * @return the string
	 */
	public static byte[] decryptByteAES(byte[] sSrc, String sKey){
		
		//验证密钥规则
		if (sKey == null || sKey.length() != 16){
			throw new FrameworkException("AES,密钥格式不正确");
		}
		
		byte[] encrypted = sSrc;
		
		try {
			byte[] raw = sKey.getBytes("utf-8");
			SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.DECRYPT_MODE, skeySpec);
			
			byte[] original = cipher.doFinal(encrypted);
			return original;
		} catch (Exception e) {
			throw new FrameworkException(e);
		}
	}
	/**
	 * AES解密.
	 *
	 * @param sSrc 输入值
	 * @param sKey 16位密钥
	 * @return the string
	 */
	public static byte[] decryptByteAES(byte[] sSrc){
		return decryptByteAES(sSrc, KEY_16);
	}
	/**
	 * Decrypt AES. 使用固定的默认密钥进行解密
	 *
	 * @param sSrc 解密源数据
	 * @return the string
	 */
	public static String decryptAES(String sSrc){
		return decryptAES(sSrc,KEY_16);
	}
	/**
	 * 生成公钥私钥对
	 * @return
	 */
	public static Map<String, String> generaterKey(String key){
		Map<String, String> rs = new HashMap<String, String>();
		 try {
			KeyPairGenerator keygen =KeyPairGenerator .getInstance("RSA");
			SecureRandom secrand = new SecureRandom();
			secrand.setSeed(key.getBytes()); // 初始化随机产生器
			keygen.initialize(512, secrand);
			KeyPair keys = keygen.genKeyPair();

			PublicKey pubkey = keys.getPublic();
			PrivateKey prikey = keys.getPrivate();
			byte[] pubKey = Base64.encodeBase64(pubkey.getEncoded());
			byte[] priKey = Base64.encodeBase64(prikey.getEncoded());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		 return rs;
	}
}
